package com.yitao.cms.service.operatorLog;

import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.skipper.base.bean.CommonStatus;
import com.skipper.base.bean.DataOutput;
import com.skipper.base.bean.PagedInput;
import com.skipper.base.bean.PagedOutput;
import com.skipper.base.data.querydsl.PredicateBuilder;
import com.skipper.base.service.GenericEntityService;
import com.yitao.client.dto.svclog.YitaoSensitiveWordsDto;
import com.yitao.client.model.svclog.QYitaoSensitiveWordsModel;
import com.yitao.client.model.svclog.YitaoSensitiveWordsModel;
import com.yitao.cms.constant.UserSession;
import com.yitao.cms.utils.RedisUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Date: 2019/10/25 11:14
 * @Author: Kien
 */
@Service
public class YitaoSensitiveWordsService extends GenericEntityService<YitaoSensitiveWordsModel, YitaoSensitiveWordsDto, QYitaoSensitiveWordsModel> {
    @Autowired
    private RedisUtil redisUtil;

    public YitaoSensitiveWordsService(EntityManager entityManager) {
        super(entityManager);
    }

    /**
     * 功能描述: 查询敏感词
     *
     * @param sensitiveWords 敏感词
     * @param pageNo
     * @param pageSize
     *
     * @return
     * @auther Kien
     * @date 2019/10/25 11:18
     */
    public PagedOutput<YitaoSensitiveWordsDto> findSensitiveWords(String sensitiveWords, int pageNo, int pageSize) {
        PagedInput pagedInput = new PagedInput(pageSize, pageNo);
        try {
            PagedOutput<YitaoSensitiveWordsModel> pagedOutput = repository.pagingList(PredicateBuilder.conjunction()
                    .and(() -> Q.isDelete.eq(false))
                    .ifNotNullThenAnd(sensitiveWords, () -> Q.sensitiveWords.like("%" + sensitiveWords + "%"))
                    .get(), pagedInput, new OrderSpecifier<>(Order.DESC, Q.createTime));
            List<YitaoSensitiveWordsDto> list = new ArrayList<>();
            if(pagedOutput != null && pagedOutput.getData() != null && pagedOutput.getData().size() != 0) {
                list = pagedOutput.getData().stream().map(this::convertEntityToDto).collect(Collectors.toList());
            }
            return new PagedOutput(pagedInput, pagedOutput.getTotalElements(), list);
        } catch (Exception e) {
            logger.error("查询敏感词异常");
            return new PagedOutput(CommonStatus.SERVER_ERROR, pagedInput, 0, new ArrayList());
        }
    }


    /**
     * 功能描述: 新增或者编辑敏感词，(id不为空则编辑)
     *
     * @param id id
     * @param sensitiveWords 敏感词
     *
     * @return
     * @auther Kien
     * @date 2019/10/25 11:34
     */
    @Transactional
    public DataOutput addSensitiveWords(Long id, String sensitiveWords, HttpServletRequest request) {
        Long userId = UserSession.getUserIdBySession(request);
        if(null == userId) {
            logger.error("用户未登录");
            return new DataOutput(CommonStatus.UNAUTHORIZED);
        }
        if(StringUtils.isBlank(sensitiveWords)) {
            logger.error("敏感词不能为空");
            return new DataOutput(CommonStatus.BAD_REQUEST.getCode(), "敏感词不能为空");
        }
        Date date = new Date();
        // 新增或者编辑敏感词库时，需要同步到redis
        if(id != null) { // 编辑
            logger.info("编辑敏感词");
            YitaoSensitiveWordsModel one = repository.findOne(PredicateBuilder.conjunction().and(() -> Q.id.eq(id)).and(() -> Q.isDelete.eq(false)).get());
            if(one == null) {
                return new DataOutput(CommonStatus.BAD_REQUEST.getCode(), "敏感词id错误");
            }
            int i = repository.updateByWhere(PredicateBuilder.conjunction().and(() -> Q.id.eq(id)).get(), it -> it.set(Q.sensitiveWords, sensitiveWords));
            if(i == 0) {
                logger.error("编辑敏感词异常");
                return new DataOutput(CommonStatus.SERVER_ERROR);
            }
            findSet(2, sensitiveWords, one.getId(), null);
            return new DataOutput();
        } else { // 新增
            logger.info("新增敏感词");
            YitaoSensitiveWordsModel yitaoSensitiveWordsModel = new YitaoSensitiveWordsModel();
            yitaoSensitiveWordsModel.setIsDelete(false);
            yitaoSensitiveWordsModel.setSensitiveWords(sensitiveWords);
            yitaoSensitiveWordsModel.setCreateTime(date);
            yitaoSensitiveWordsModel.setCreateBy(userId.toString());
            YitaoSensitiveWordsModel save = repository.save(yitaoSensitiveWordsModel);
            if(save == null) {
                logger.error("新增敏感词异常");
                return new DataOutput(CommonStatus.SERVER_ERROR);
            }
            findSet(1, sensitiveWords, null, null);
            return new DataOutput();
        }
    }

    /**
     * 功能描述: 新增或者编辑敏感词汇同步redis
     *
     * @param type 1: 新增 2:编辑 3:删除
     * @param content 敏感词
     * @param id 敏感词
     * @param idList 需要删除的敏感词汇列表
     *
     * @return
     * @auther Kien
     * @date 2019/12/2 16:45
     */
    public void findSet(int type, String content, Long id, List<Long> idList){
        List<YitaoSensitiveWordsModel> all = repository.findAll(PredicateBuilder.conjunction().and(() -> Q.isDelete.eq(false)).get());
        Set<String> set = new HashSet<>();
        if(1 == type) { // 新增

            set.add(content);
        }
        if(!CollectionUtils.isEmpty(all)) {
            for(YitaoSensitiveWordsModel yitaoSensitiveWordsModel: all) {
                String sensitiveWords = yitaoSensitiveWordsModel.getSensitiveWords();
                Long sensitiveId = yitaoSensitiveWordsModel.getId();
                if(org.apache.commons.lang3.StringUtils.isNotBlank(sensitiveWords)) {
                    if(2 == type) { // 编辑
                        if(sensitiveId.equals(id)) {
                            set.add(content);
                        } else {
                            set.add(sensitiveWords);
                        }
                    } else if(3 == type) { // 删除(当前id不能写入)
                        if(idList.contains(sensitiveId)) { // 如果当前id处于删除列表中，这个敏感词不需要加入redis中
                            continue;
                        } else {
                            set.add(sensitiveWords);
                        }
                    } else {
                        set.add(sensitiveWords); // 其他直接写入
                    }
                }
            }
        }
        if(!CollectionUtils.isEmpty(set)) {
            redisUtil.delObject("sensitiveWords");
            Object sensitiveWords = redisUtil.getObject("sensitiveWords");
            redisUtil.setObejct("sensitiveWords", set);
        }
    }

    /**
     * 功能描述: 删除敏感词
     *
     * @param ids 敏感词列表id
     * @param request
     *
     * @return
     * @auther Kien
     * @date 2019/10/25 11:44
     */
    @Transactional
    public DataOutput delSensitiveWords(List<Long> ids, HttpServletRequest request) {
        if(ids == null || ids.size() == 0) {
            logger.error("要删除的列表id为空");
            return new DataOutput(CommonStatus.BAD_REQUEST.getCode(), "要删除的列表id为空");
        }
        int i = repository.updateByWhere(PredicateBuilder.conjunction().and(() -> Q.id.in(ids)).get(), it -> it.set(Q.isDelete, true));
        if(i == 0) {
            logger.error("批量删除失败");
            return new DataOutput(CommonStatus.SERVER_ERROR);
        }
        findSet(3, null, null, ids);
        return new DataOutput();
    }

    /**
     * 功能描述: 导入敏感词
     *
     * @param file 敏感词文本
     *
     * @return
     * @auther Kien
     * @date 2019/10/25 14:15
     */
    @Transactional
    public DataOutput importSensitiveWords(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            InputStreamReader reader = new InputStreamReader(inputStream, "GB2312");
            BufferedReader br = new BufferedReader(reader);
            Date time=new Date();
            String line;
            List<YitaoSensitiveWordsModel> list = new ArrayList<>();
            Date date = new Date();
            while ((line = br.readLine()) != null) {
                // 一次读入一行数据
                YitaoSensitiveWordsModel yitaoSensitiveWordsModel = new YitaoSensitiveWordsModel();
                if(line != null && line != ""){
                   yitaoSensitiveWordsModel.setSensitiveWords(line);
                   yitaoSensitiveWordsModel.setCreateBy("5"); // Kien
                   yitaoSensitiveWordsModel.setCreateTime(date);
                   yitaoSensitiveWordsModel.setIsDelete(false);
                }
                list.add(yitaoSensitiveWordsModel);
            }
            reader.close();
            repository.save(list);
            return new DataOutput();
        } catch (Exception e) {
            return new DataOutput(CommonStatus.SERVER_ERROR);
        }

    }

}
